/* IETF Validation tests */
#include <stdio.h>
#include "unabto_env_base.h"

#if NABTO_ENABLE_TEST_CODE

#include "crypto/unabto_hmac_sha256_test.h"
#include "crypto/unabto_hmac_sha256.h"
#include "crypto/unabto_sha256.h"

bool test(const __ROM char *vector, unsigned char *digest,
        unsigned int digest_size) {
    char output[2 * SHA256_DIGEST_SIZE + 1];
    int i;

    output[2 * digest_size] = '\0';

    for (i = 0; i < (int) digest_size; i++) {
        sprintf(output + 2 * i, "%02x", digest[i]);
    }

    NABTO_LOG_INFO(("H: %s", output));

    if (strcmpram2pgm(vector, output)) {
        NABTO_LOG_INFO(("Test failed."));
        return false;
    }
    return true;
}

/* HMAC-SHA-256 */
//static const __ROM char vector1[] = "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7";
//static const __ROM char vector2[] = "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843";
//static const __ROM char vector3[] = "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe";
//static const __ROM char vector4[] = "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b";
//static const __ROM char vector5[] = "a3b6167473100ee06e0c796c2955552b";
//static const __ROM char vector6[] = "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54";
static __ROM char vector[] = "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2";

//static const unsigned char key0[20] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
//    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
//static const unsigned char key1[5] = "Jefe"; // only four bytes used!
//static const unsigned char key2[20] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
//    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
//static const uint8_t key3[25] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
//static const unsigned char key4[20] = {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
//    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c};

static unsigned char key[132] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
    0xaa, 0x00};

//static const __ROM unsigned char key6[131] = key5;


//static const unsigned char message3[51] = {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
//    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
//    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
//    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
//    0xdd, 0xdd, 0x00};
//static const unsigned char message4[51] = {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
//    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
//    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
//    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
//    0xcd, 0xcd, 0x00};

//static const unsigned char message1[] = "Hi There";
//static const unsigned char message2[] = "what do ya want for nothing?";
//static const unsigned char message5[] = "Test With Truncation";
//static const unsigned char message6[] = "Test Using Larger Than Block-Size Key - Hash Key First";
static text message_rom = "This is a test using a larger than block-size key "
        "and a larger than block-size data. The key needs"
        " to be hashed before being used by the HMAC algorithm.";


//#pragma udata big_mem
static uint8_t message[160];
static uint8_t digest[SHA256_DIGEST_SIZE];
static uint8_t digest2[SHA256_DIGEST_SIZE];
//#pragma udata

bool hmac_sha256_test(void) {
    int r;
    unsigned char mac[SHA256_DIGEST_SIZE];
    unsigned int key_len = 131;
    size_t mac_size;
    uint16_t messageLength = strlenpgm(message_rom);

    memcpypgm2ram(message, message_rom, messageLength);

    NABTO_LOG_INFO(("HMAC-SHA-2 IETF Validation tests"));

        mac_size = SHA256_DIGEST_SIZE;
    unabto_sha256(message, messageLength, digest);
    unabto_hmac_sha256(key, key_len, message, messageLength, mac, mac_size);
    unabto_sha256(message, messageLength, digest2);
    r = memcmp((const void*)digest, (const void*)digest2, SHA256_DIGEST_SIZE);
    if (r != 0) {
        NABTO_LOG_TRACE(("The hmac changed the message"));
        return false;
    }

    if (!test(vector, mac, mac_size)) {
        return false;
    }

    return true;
}

#else
static char dummy;
#endif
